This repository has no description
1import type { Did } from "@atcute/lexicons/syntax";
2import { createBobbinClient } from "$lib/api/client";
3import { count } from "$lib/api/count";
4import { toHttpError } from "$lib/api/load";
5import {
6 fetchReposPage,
7 fetchStringsPage,
8 fetchStarredPage,
9 fetchPeoplePage,
10 fetchVouchesPage,
11 fetchPinned
12} from "$lib/components/profile/pages";
13import type { PageLoad } from "./$types";
14
15const TABS = [
16 "overview",
17 "repos",
18 "starred",
19 "strings",
20 "followers",
21 "following",
22 "vouches"
23] as const;
24type Tab = (typeof TABS)[number];
25
26const normalizeTab = (raw: string | null): Tab =>
27 TABS.includes(raw as Tab) ? (raw as Tab) : "overview";
28
29export const load: PageLoad = async (event) => {
30 const parent = await event.parent();
31 const tab = normalizeTab(event.url.searchParams.get("tab"));
32
33 if (parent.notJoined) return { tab: "overview" as const, overview: { pinned: [] } };
34
35 const ctx = createBobbinClient({ serviceUrl: parent.publicConfig.bobbinUrl, fetch: event.fetch });
36 const did = parent.identity.did as Did;
37 const handle = parent.identity.handle;
38 const viewerDid = parent.auth?.did;
39
40 try {
41 switch (tab) {
42 case "repos": {
43 const q = event.url.searchParams.get("q")?.trim();
44 const page = await fetchReposPage(ctx, { did, handle, viewerDid, q: q || undefined });
45 return { tab: "repos" as const, repos: page.items, cursor: page.cursor };
46 }
47 case "strings": {
48 const page = await fetchStringsPage(ctx, { did, handle });
49 return { tab: "strings" as const, strings: page.items, cursor: page.cursor };
50 }
51 case "followers":
52 case "following": {
53 const page = await fetchPeoplePage(ctx, { did, viewerDid, direction: tab });
54 return { tab, people: page.items, cursor: page.cursor } as const;
55 }
56 case "vouches": {
57 const page = await fetchVouchesPage(ctx, { did });
58 const outgoing = await count(ctx, "sh.tangled.graph.countVouchesBy", did);
59 return {
60 tab: "vouches" as const,
61 vouches: page.items,
62 cursors: page.cursors,
63 vouchTotal: parent.counts.vouches + outgoing.count,
64 isSelf: viewerDid === did,
65 profileHandle: handle
66 };
67 }
68 case "starred": {
69 const page = await fetchStarredPage(ctx, { did, viewerDid });
70 return { tab: "starred" as const, stars: page.items, cursor: page.cursor };
71 }
72 case "overview":
73 default: {
74 const pinned = await fetchPinned(ctx, {
75 keys: parent.profile?.pinnedRepositories ?? [],
76 handle,
77 viewerDid
78 });
79 return { tab: "overview" as const, overview: { pinned } };
80 }
81 }
82 } catch (cause) {
83 console.error("Page load error:", cause);
84 toHttpError(cause, "Could not load profile data");
85 }
86};